module local_address_space_access(
    input epu_clk,
    input rst_n,

    input pdi_epu_re,
    input [15:0] pdi_epu_addr,
    output reg [7:0] epu_pdi_dout,
    output reg epu_pdi_dout_valid,

    input [7:0] epu_pdi_dout_esc_information,
    input epu_pdi_dout_valid_esc_information,
    input [7:0] epu_pdi_dout_station_address,
    input epu_pdi_dout_valid_station_address,
    input [7:0] epu_pdi_dout_write_protection,
    input epu_pdi_dout_valid_write_protection,
    input [7:0] epu_pdi_dout_datalink_layer,
    input epu_pdi_dout_valid_datalink_layer,
    input [7:0] epu_pdi_dout_application_layer,
    input epu_pdi_dout_valid_application_layer,
    input [7:0] epu_pdi_dout_configuration,
    input epu_pdi_dout_valid_configuration,
    input [7:0] epu_pdi_dout_interrupts,
    input epu_pdi_dout_valid_interrupts,
    input [7:0] epu_pdi_dout_error_counters,
    input epu_pdi_dout_valid_error_counters,
    input [7:0] epu_pdi_dout_watchdogs,
    input epu_pdi_dout_valid_watchdogs,
    input [7:0] epu_pdi_dout_sii_eeprom_interface,
    input epu_pdi_dout_valid_sii_eeprom_interface,
    input [7:0] epu_pdi_dout_mii_management_interface,
    input epu_pdi_dout_valid_mii_management_interface,
    input [7:0] epu_pdi_dout_fmmu,
    input epu_pdi_dout_valid_fmmu,
    input [7:0] epu_pdi_dout_syncmanager,
    input epu_pdi_dout_valid_syncmanager,
    input [7:0] epu_pdi_dout_distributed_clock,
    input epu_pdi_dout_valid_distributed_clock,

    input ecat_epu_re,
    input [15:0] ecat_epu_addr,
    output reg [7:0] epu_ecat_dout,
    output reg epu_ecat_dout_valid,

    input [7:0] epu_ecat_dout_esc_information,
    input epu_ecat_dout_valid_esc_information,
    input [7:0] epu_ecat_dout_station_address,
    input epu_ecat_dout_valid_station_address,
    input [7:0] epu_ecat_dout_write_protection,
    input epu_ecat_dout_valid_write_protection,
    input [7:0] epu_ecat_dout_datalink_layer,
    input epu_ecat_dout_valid_datalink_layer,
    input [7:0] epu_ecat_dout_application_layer,
    input epu_ecat_dout_valid_application_layer,
    input [7:0] epu_ecat_dout_configuration,
    input epu_ecat_dout_valid_configuration,
    input [7:0] epu_ecat_dout_interrupts,
    input epu_ecat_dout_valid_interrupts,
    input [7:0] epu_ecat_dout_error_counters,
    input epu_ecat_dout_valid_error_counters,
    input [7:0] epu_ecat_dout_watchdogs,
    input epu_ecat_dout_valid_watchdogs,
    input [7:0] epu_ecat_dout_sii_eeprom_interface,
    input epu_ecat_dout_valid_sii_eeprom_interface,
    input [7:0] epu_ecat_dout_mii_management_interface,
    input epu_ecat_dout_valid_mii_management_interface,
    input [7:0] epu_ecat_dout_fmmu,
    input epu_ecat_dout_valid_fmmu,
    input [7:0] epu_ecat_dout_syncmanager,
    input epu_ecat_dout_valid_syncmanager,
    input [7:0] epu_ecat_dout_distributed_clock,
    input epu_ecat_dout_valid_distributed_clock
);
    /* pdi read */
    reg pdi_epu_re_latch;
    reg [15:0] pdi_epu_addr_latch;

    always@(posedge epu_clk or negedge rst_n) begin
        if(!rst_n) begin
            pdi_epu_re_latch <= 0;
            pdi_epu_addr_latch <= 16'b0;
        end
        else begin
            pdi_epu_re_latch <= pdi_epu_re;
            pdi_epu_addr_latch <= pdi_epu_addr;
        end
    end

    always@(*) begin
        if(pdi_epu_re_latch) begin
            if(pdi_epu_addr_latch >= 16'h0000 && pdi_epu_addr_latch <= 16'h0009) begin
                epu_pdi_dout = epu_pdi_dout_esc_information;
                epu_pdi_dout_valid = epu_pdi_dout_valid_esc_information;
            end
            else if(pdi_epu_addr_latch >=16'h0010 && pdi_epu_addr_latch<=16'h0013) begin
                epu_pdi_dout = epu_pdi_dout_station_address;
                epu_pdi_dout_valid = epu_pdi_dout_valid_station_address;
            end
            else if(pdi_epu_addr_latch >= 16'h0020 && pdi_epu_addr_latch <= 16'h0031) begin
                epu_pdi_dout = epu_pdi_dout_write_protection;
                epu_pdi_dout_valid = epu_pdi_dout_valid_write_protection;
            end
            else if(pdi_epu_addr_latch >= 16'h0040 && pdi_epu_addr_latch <= 16'h0111) begin
                epu_pdi_dout = epu_pdi_dout_datalink_layer;
                epu_pdi_dout_valid = epu_pdi_dout_valid_datalink_layer;
            end
            else if(pdi_epu_addr_latch >= 16'h0120 && pdi_epu_addr_latch <= 16'h0139) begin
                epu_pdi_dout = epu_pdi_dout_application_layer;
                epu_pdi_dout_valid = epu_pdi_dout_valid_application_layer;
            end
            else if(pdi_epu_addr_latch >= 16'h0140 && pdi_epu_addr_latch <= 16'h0153) begin
                epu_pdi_dout = epu_pdi_dout_configuration;
                epu_pdi_dout_valid = epu_pdi_dout_valid_configuration; 
            end
            else if(pdi_epu_addr_latch >= 16'h0200 && pdi_epu_addr_latch <= 16'h0223) begin
                epu_pdi_dout = epu_pdi_dout_interrupts;
                epu_pdi_dout_valid = epu_pdi_dout_valid_interrupts;
            end
            else if(pdi_epu_addr_latch >= 16'h0300 && pdi_epu_addr_latch <= 16'h0313) begin
                epu_pdi_dout = epu_pdi_dout_error_counters;
                epu_pdi_dout_valid = epu_pdi_dout_valid_error_counters;
            end
            else if(pdi_epu_addr_latch >= 16'h0400 && pdi_epu_addr_latch <= 16'h0443) begin
                epu_pdi_dout = epu_pdi_dout_watchdogs;
                epu_pdi_dout_valid = epu_pdi_dout_valid_watchdogs;
            end
            else if(pdi_epu_addr_latch >= 16'h0500 && pdi_epu_addr_latch <= 16'h050F) begin
                epu_pdi_dout = epu_pdi_dout_sii_eeprom_interface;
                epu_pdi_dout = epu_pdi_dout_sii_eeprom_interface; 
            end
            else if(pdi_epu_addr_latch >= 16'h0510 && pdi_epu_addr_latch <= 16'h051B) begin
                epu_pdi_dout = epu_pdi_dout_mii_management_interface;
                epu_pdi_dout_valid = epu_pdi_dout_valid_mii_management_interface;
            end
            else if(pdi_epu_addr_latch >= 16'h0600 && pdi_epu_addr_latch <= 16'h06FF) begin
                epu_pdi_dout = epu_pdi_dout_fmmu;
                epu_pdi_dout_valid = epu_pdi_dout_valid_fmmu;
            end
            else if(pdi_epu_addr_latch >= 16'h0800 && pdi_epu_addr_latch <= 16'h087F) begin
                epu_pdi_dout = epu_pdi_dout_syncmanager;
                epu_pdi_dout_valid = epu_pdi_dout_valid_syncmanager; 
            end
            else if(pdi_epu_addr_latch >= 16'h0900 && pdi_epu_addr_latch <= 16'h09FF) begin
                epu_pdi_dout = epu_pdi_dout_distributed_clock;
                epu_pdi_dout_valid = epu_pdi_dout_valid_distributed_clock;
            end
            else if(pdi_epu_addr_latch >= 16'h0F80 && pdi_epu_addr_latch <= 16'hFFFF) begin
                epu_pdi_dout = epu_pdi_dout_syncmanager;
                epu_pdi_dout_valid = epu_pdi_dout_valid_syncmanager;
            end
            else begin
                epu_pdi_dout = 8'b0;
                epu_pdi_dout_valid = 0;
            end
        end
        else begin
            epu_pdi_dout = 8'b0;
            epu_pdi_dout_valid = 0;
        end
    end
    /* ecat read */
    reg ecat_epu_re_latch;
    reg [15:0] ecat_epu_addr_latch;

    always@(posedge epu_clk or negedge rst_n) begin
        if(!rst_n) begin
            ecat_epu_re_latch <= 0;
            ecat_epu_addr_latch <= 16'b0;
        end
        else begin
            ecat_epu_re_latch <= ecat_epu_re;
            ecat_epu_addr_latch <= ecat_epu_addr;
        end
    end

    always@(*) begin
        if(ecat_epu_re_latch) begin
            if(ecat_epu_addr_latch >= 16'h0000 && ecat_epu_addr_latch <= 16'h0009) begin
                epu_ecat_dout = epu_ecat_dout_esc_information;
                epu_ecat_dout_valid = epu_ecat_dout_valid_esc_information;
            end
            else if(ecat_epu_addr_latch>=16'h0010 && ecat_epu_addr_latch<=16'h0013) begin
                epu_ecat_dout = epu_ecat_dout_station_address;
                epu_ecat_dout_valid = epu_ecat_dout_valid_station_address;
            end
            else if(ecat_epu_addr_latch >= 16'h0020 && ecat_epu_addr_latch <= 16'h0031) begin
                epu_ecat_dout = epu_ecat_dout_write_protection;
                epu_ecat_dout_valid = epu_ecat_dout_valid_write_protection;
            end
            else if(ecat_epu_addr_latch >= 16'h0040 && ecat_epu_addr_latch <= 16'h0111) begin
                epu_ecat_dout = epu_ecat_dout_datalink_layer;
                epu_ecat_dout_valid = epu_ecat_dout_valid_datalink_layer;
            end
            else if(ecat_epu_addr_latch >= 16'h0120 && ecat_epu_addr_latch <= 16'h0139) begin
                epu_ecat_dout = epu_ecat_dout_application_layer;
                epu_ecat_dout_valid = epu_ecat_dout_valid_application_layer;
            end
            else if(ecat_epu_addr_latch >= 16'h0140 && ecat_epu_addr_latch <= 16'h0153) begin
                epu_ecat_dout = epu_ecat_dout_configuration;
                epu_ecat_dout_valid = epu_ecat_dout_valid_configuration; 
            end
            else if(ecat_epu_addr_latch >= 16'h0200 && ecat_epu_addr_latch <= 16'h0223) begin
                epu_ecat_dout = epu_ecat_dout_interrupts;
                epu_ecat_dout_valid = epu_ecat_dout_valid_interrupts;
            end
            else if(ecat_epu_addr_latch >= 16'h0300 && ecat_epu_addr_latch <= 16'h0313) begin
                epu_ecat_dout = epu_ecat_dout_error_counters;
                epu_ecat_dout_valid = epu_ecat_dout_valid_error_counters;
            end
            else if(ecat_epu_addr_latch >= 16'h0400 && ecat_epu_addr_latch <= 16'h0443) begin
                epu_ecat_dout = epu_ecat_dout_watchdogs;
                epu_ecat_dout_valid = epu_ecat_dout_valid_watchdogs;
            end
            else if(ecat_epu_addr_latch >= 16'h0500 && ecat_epu_addr_latch <= 16'h050F) begin
                epu_ecat_dout = epu_ecat_dout_sii_eeprom_interface;
                epu_ecat_dout = epu_ecat_dout_sii_eeprom_interface; 
            end
            else if(ecat_epu_addr_latch >= 16'h0510 && ecat_epu_addr_latch <= 16'h051B) begin
                epu_ecat_dout = epu_ecat_dout_mii_management_interface;
                epu_ecat_dout_valid = epu_ecat_dout_valid_mii_management_interface;
            end
            else if(ecat_epu_addr_latch >= 16'h0600 && ecat_epu_addr_latch <= 16'h06FF) begin
                epu_ecat_dout = epu_ecat_dout_fmmu;
                epu_ecat_dout_valid = epu_ecat_dout_valid_fmmu;
            end
            else if(ecat_epu_addr_latch >= 16'h0800 && ecat_epu_addr_latch <= 16'h087F) begin
                epu_ecat_dout = epu_ecat_dout_syncmanager;
                epu_ecat_dout_valid = epu_ecat_dout_valid_syncmanager; 
            end
            else if(ecat_epu_addr_latch >= 16'h0900 && ecat_epu_addr_latch <= 16'h09FF) begin
                epu_ecat_dout = epu_ecat_dout_distributed_clock;
                epu_ecat_dout_valid = epu_ecat_dout_valid_distributed_clock;
            end
            else if(ecat_epu_addr_latch >= 16'h0F80 && ecat_epu_addr_latch <= 16'hFFFF) begin
                epu_ecat_dout = epu_ecat_dout_syncmanager;
                epu_ecat_dout_valid = epu_ecat_dout_valid_syncmanager;
            end
            else begin
                epu_ecat_dout = 8'b0;
                epu_ecat_dout_valid = 0;
            end
        end
        else begin
            epu_ecat_dout = 8'b0;
            epu_ecat_dout_valid = 0;
        end
    end
endmodule